package top.riske.gen3d.util;

import com.tencentcloudapi.ai3d.v20250513.Ai3dClient;
import com.tencentcloudapi.ai3d.v20250513.models.*;
import com.tencentcloudapi.common.AbstractModel;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import org.springframework.http.HttpStatus;
import top.riske.gen3d.DTO.HunyuanInputMultiViewImagesDto;
import top.riske.gen3d.http.exception.BisException;

import java.util.List;

public class Tencent3DUtils {

    public static void main(String[] args) throws TencentCloudSDKException {
        String secretId = "AKIDxtcPBrMet45taFj3ITTGrFWkleKqA0iD";
        String secretKey = "PbmlW5RZUCh181hHn7E8pJbgbVIrEOL4";
        String region = "ap-guangzhou";
        String prompt = "A man is walking in a park";
//        submitHunyuanTo3DJob(secretId,secretKey,region,prompt);

        String jobId = "1362311529604980736";
//        queryHunyuanTo3DJob(secretId,secretKey,region,jobId);
    }

    /**
     * 腾讯3D提交任务,文生3D图
     * @param secretId 密钥ID
     * @param secretKey 密钥
     * @param region 地域
     * @param prompt 提示语
     * @return 响应,如{"JobId":"1362311529604980736","RequestId":"6b726e7e-4ad9-4484-8539-85455a801f13"}
     * @throws TencentCloudSDKException 腾讯云异常
     */
    public static SubmitHunyuanTo3DJobResponse submitHunyuanTo3DJobByTextForNormal(String secretId,String secretKey, String region, String prompt) throws TencentCloudSDKException {
        // 获取Ai3dClient示例对象
        Ai3dClient client = getAi3dClient(secretId, secretKey, region);
        // 实例化一个请求对象,每个接口都会对应一个request对象
        SubmitHunyuanTo3DJobRequest req = new SubmitHunyuanTo3DJobRequest();
        // 设置请求参数 - 提示语
        req.setPrompt(prompt);
        // 返回的resp是一个SubmitHunyuanTo3DJobResponse的实例，与请求对象对应
        return client.SubmitHunyuanTo3DJob(req);
    }

    /**
     * 腾讯3D提交任务,图生3D图
     * @param secretId 密钥ID
     * @param secretKey 密钥
     * @param region 地域
     * @param imageList 图片信息
     * @return 响应,如{"JobId":"1362311529604980736","RequestId":"6b726e7e-4ad9-4484-8539-85455a801f13"}
     * @throws TencentCloudSDKException 腾讯云异常
     */
    public static SubmitHunyuanTo3DJobResponse submitHunyuanTo3DJobByImageForNormal(String secretId,String secretKey, String region, List<HunyuanInputMultiViewImagesDto> imageList) throws TencentCloudSDKException {
        // 获取Ai3dClient示例对象
        Ai3dClient client = getAi3dClient(secretId, secretKey, region);
        // 实例化一个请求对象,每个接口都会对应一个request对象
        SubmitHunyuanTo3DJobRequest req = new SubmitHunyuanTo3DJobRequest();
        // 若只有一个图片
        if(imageList.size() == 1){
            // 设置请求参数 - 单张图片
            req.setImageUrl(imageList.getFirst().getViewImageUrl());
        }else{
            // 设置主视图图片
            req.setImageUrl(HunyuanInputMultiViewImagesDto.findFrontViewImage(imageList).getViewImageUrl());
            // 设置请求参数 - 全视角图片
            req.setMultiViewImages(HunyuanInputMultiViewImagesDto.toViewImageArray(imageList));
            // 返回的resp是一个SubmitHunyuanTo3DJobResponse的实例，与请求对象对应
        }
        return client.SubmitHunyuanTo3DJob(req);
    }


    /**
     * 腾讯3D提交任务,文生3D图，pro版本
     * @param secretId 密钥ID
     * @param secretKey 密钥
     * @param region 地域
     * @param prompt 提示语
     * @param enablePBR 是否启用PBR材质生成
     * @param faceCount 模型面数40000-500000
     * @param generateType 模型生成方式，可选值：
     *                      Normal：可生成带纹理的几何模型。
     *                      LowPoly：可生成智能减面后的模型。
     *                      Geometry：可生成不带纹理的几何模型（白模），选择此任务时，EnablePBR参数不生效。
     *                      Sketch：可输入草图或线稿图生成模型，此模式下prompt和ImageUrl/ImageBase64可一起输入。
     * @return 响应,如{"JobId":"1362311529604980736","RequestId":"6b726e7e-4ad9-4484-8539-85455a801f13"}
     * @throws TencentCloudSDKException 腾讯云异常
     */
    public static SubmitHunyuanTo3DProJobResponse submitHunyuanTo3DJobByTextForPro(String secretId,String secretKey,
                        String region, String prompt, Boolean enablePBR,
                        Integer faceCount,String generateType) throws TencentCloudSDKException {
        // 获取Ai3dClient示例对象
        Ai3dClient client = getAi3dClient(secretId, secretKey, region);
        // 实例化一个请求对象,每个接口都会对应一个request对象
        SubmitHunyuanTo3DProJobRequest req = new SubmitHunyuanTo3DProJobRequest();
        // 设置请求参数 - 提示语
        req.setPrompt(prompt);
        req.setEnablePBR(enablePBR);
        req.setFaceCount(Long.valueOf(faceCount));
        req.setGenerateType(generateType);
        // 返回的请求对象
        return client.SubmitHunyuanTo3DProJob(req);
    }

    /**
     * 腾讯3D提交任务,图生3D图, pro版本
     * @param secretId 密钥ID
     * @param secretKey 密钥
     * @param region 地域
     * @param imageList 图片信息
     * @return 响应,如{"JobId":"1362311529604980736","RequestId":"6b726e7e-4ad9-4484-8539-85455a801f13"}
     * @throws TencentCloudSDKException 腾讯云异常
     */
    public static SubmitHunyuanTo3DProJobResponse submitHunyuanTo3DJobByImageForPro(String secretId,
             String secretKey, String region, List<HunyuanInputMultiViewImagesDto> imageList,
             Boolean enablePBR, Integer faceCount,String generateType) throws TencentCloudSDKException {
        // 获取Ai3dClient示例对象
        Ai3dClient client = getAi3dClient(secretId, secretKey, region);
        // 实例化一个请求对象,每个接口都会对应一个request对象
        SubmitHunyuanTo3DProJobRequest req = new SubmitHunyuanTo3DProJobRequest();
        // 若只有一个图片
        if(imageList.size() == 1){
            // 设置请求参数 - 单张图片
            req.setImageUrl(imageList.getFirst().getViewImageUrl());
        }else{
            // 设置主视图图片
            req.setImageUrl(HunyuanInputMultiViewImagesDto.findFrontViewImage(imageList).getViewImageUrl());
            // 设置请求参数 - 全视角图片
            req.setMultiViewImages(HunyuanInputMultiViewImagesDto.toViewImageArray(imageList));
            // 返回的resp是一个SubmitHunyuanTo3DJobResponse的实例，与请求对象对应
        }
        req.setEnablePBR(enablePBR);
        req.setFaceCount(Long.valueOf(faceCount));
        req.setGenerateType(generateType);
        return client.SubmitHunyuanTo3DProJob(req);
    }


    /**
     * 腾讯3D提交任务,文生3D图，Rapid版本
     * @param secretId 密钥ID
     * @param secretKey 密钥
     * @param region 地域
     * @param prompt 提示语
     * @return 响应,如{"JobId":"1362311529604980736","RequestId":"6b726e7e-4ad9-4484-8539-85455a801f13"}
     * @throws TencentCloudSDKException 腾讯云异常
     */
    public static SubmitHunyuanTo3DRapidJobResponse submitHunyuanTo3DJobByTextForRapid(String secretId,String secretKey, String region, String prompt) throws TencentCloudSDKException {
        // 获取Ai3dClient示例对象
        Ai3dClient client = getAi3dClient(secretId, secretKey, region);
        // 实例化一个请求对象,每个接口都会对应一个request对象
        SubmitHunyuanTo3DRapidJobRequest req = new SubmitHunyuanTo3DRapidJobRequest();
        // 设置请求参数 - 提示语
        req.setPrompt(prompt);
        // 返回的resp是一个SubmitHunyuanTo3DRapidJobResponse的实例，与请求对象对应
        return client.SubmitHunyuanTo3DRapidJob(req);
    }

    /**
     * 腾讯3D提交任务,图生3D图，Rapid版本
     * @param secretId 密钥ID
     * @param secretKey 密钥
     * @param region 地域
     * @param imageList 图片信息
     * @return 响应,如{"JobId":"1362311529604980736","RequestId":"6b726e7e-4ad9-4484-8539-85455a801f13"}
     * @throws TencentCloudSDKException 腾讯云异常
     */
    public static SubmitHunyuanTo3DRapidJobResponse submitHunyuanTo3DJobByImageForRapid(String secretId,String secretKey, String region, List<HunyuanInputMultiViewImagesDto> imageList) throws TencentCloudSDKException {
        // 获取Ai3dClient示例对象
        Ai3dClient client = getAi3dClient(secretId, secretKey, region);
        // 实例化一个请求对象,每个接口都会对应一个request对象
        SubmitHunyuanTo3DRapidJobRequest req = new SubmitHunyuanTo3DRapidJobRequest();
        // 若只有一个图片
        if(imageList.size() == 1){
            // 设置请求参数 - 单张图片
            req.setImageUrl(imageList.getFirst().getViewImageUrl());
        }else{
            throw new BisException(HttpStatus.BAD_REQUEST, "Rapid版本只支持单张图片生成");
        }
        return client.SubmitHunyuanTo3DRapidJob(req);
    }



    /**
     * 腾讯3D查询任务，Normal 版本
     * @param secretId 密钥ID
     * @param secretKey 密钥
     * @param region 地域
     * @param jobId 任务ID
     * @return 响应,如{"Status":"DONE","ErrorCode":"","ErrorMessage":"","ResultFile3Ds":[{"Type":"OBJ","Url":"https://hunyuan-prod-1258344699.cos.ap-guangzhou.tencentcos.cn/3d/output/1257289198/6b726e7e-4ad9-4484-8539-85455a801f13_0.zip?q-sign-algorithm=sha1&q-ak=AKIDpRovliU1IJ5ctufBSVIq8AwTlnZ5MN8d&q-sign-time=1758695170%3B1758781570&q-key-time=1758695170%3B1758781570&q-header-list=host&q-url-param-list=&q-signature=c47edccc3cbb601245ddf2de8a39c618f1305fbd","PreviewImageUrl":"https://hunyuan-prod-1258344699.cos.ap-guangzhou.tencentcos.cn/%2F3d/output/1257289198/preview_6b726e7e-4ad9-4484-8539-85455a801f13_0.png?q-sign-algorithm=sha1&q-ak=AKIDpRovliU1IJ5ctufBSVIq8AwTlnZ5MN8d&q-sign-time=1758695170%3B1758781570&q-key-time=1758695170%3B1758781570&q-header-list=host&q-url-param-list=&q-signature=90f6e17da43901ffc3d77468ae59dbdd3829d7f3"}],"RequestId":"7fd99736-6a2c-476a-bb51-8f6786443fc4"}
     * @throws TencentCloudSDKException 腾讯云异常
     */
    public static QueryHunyuanTo3DJobResponse queryHunyuanTo3DJobForNormal(String secretId,String secretKey, String region, String jobId) throws TencentCloudSDKException {
        Ai3dClient client = getAi3dClient(secretId, secretKey, region);
        // 实例化一个请求对象,每个接口都会对应一个request对象
        QueryHunyuanTo3DJobRequest req = new QueryHunyuanTo3DJobRequest();
        // 设置请求参数 - 任务ID
        req.setJobId(jobId);
        // 返回的resp是一个QueryHunyuanTo3DJobResponse的实例，与请求对象对应
        QueryHunyuanTo3DJobResponse resp = client.QueryHunyuanTo3DJob(req);
        // 输出json格式的字符串回包
        System.out.println(AbstractModel.toJsonString(resp));
        return resp;
    }


    /**
     * 腾讯3D查询任务，pro版本
     * @param secretId 密钥ID
     * @param secretKey 密钥
     * @param region 地域
     * @param jobId 任务ID
     * @return 响应,如{"Status":"DONE","ErrorCode":"","ErrorMessage":"","ResultFile3Ds":[{"Type":"OBJ","Url":"https://hunyuan-prod-1258344699.cos.ap-guangzhou.tencentcos.cn/3d/output/1257289198/6b726e7e-4ad9-4484-8539-85455a801f13_0.zip?q-sign-algorithm=sha1&q-ak=AKIDpRovliU1IJ5ctufBSVIq8AwTlnZ5MN8d&q-sign-time=1758695170%3B1758781570&q-key-time=1758695170%3B1758781570&q-header-list=host&q-url-param-list=&q-signature=c47edccc3cbb601245ddf2de8a39c618f1305fbd","PreviewImageUrl":"https://hunyuan-prod-1258344699.cos.ap-guangzhou.tencentcos.cn/%2F3d/output/1257289198/preview_6b726e7e-4ad9-4484-8539-85455a801f13_0.png?q-sign-algorithm=sha1&q-ak=AKIDpRovliU1IJ5ctufBSVIq8AwTlnZ5MN8d&q-sign-time=1758695170%3B1758781570&q-key-time=1758695170%3B1758781570&q-header-list=host&q-url-param-list=&q-signature=90f6e17da43901ffc3d77468ae59dbdd3829d7f3"}],"RequestId":"7fd99736-6a2c-476a-bb51-8f6786443fc4"}
     * @throws TencentCloudSDKException 腾讯云异常
     */
    public static QueryHunyuanTo3DProJobResponse queryHunyuanTo3DJobForPro(String secretId,String secretKey, String region, String jobId) throws TencentCloudSDKException {
        Ai3dClient client = getAi3dClient(secretId, secretKey, region);
        // 实例化一个请求对象,每个接口都会对应一个request对象
        QueryHunyuanTo3DProJobRequest req = new QueryHunyuanTo3DProJobRequest();
        // 设置请求参数 - 任务ID
        req.setJobId(jobId);
        // 返回的resp是一个QueryHunyuanTo3DProJobResponse的实例，与请求对象对应
        QueryHunyuanTo3DProJobResponse resp = client.QueryHunyuanTo3DProJob(req);
        // 输出json格式的字符串回包
        System.out.println(AbstractModel.toJsonString(resp));
        return resp;
    }


    /**
     * 腾讯3D查询任务，rapid版本
     * @param secretId 密钥ID
     * @param secretKey 密钥
     * @param region 地域
     * @param jobId 任务ID
     * @return 响应,如{"Status":"DONE","ErrorCode":"","ErrorMessage":"","ResultFile3Ds":[{"Type":"OBJ","Url":"https://hunyuan-prod-1258344699.cos.ap-guangzhou.tencentcos.cn/3d/output/1257289198/6b726e7e-4ad9-4484-8539-85455a801f13_0.zip?q-sign-algorithm=sha1&q-ak=AKIDpRovliU1IJ5ctufBSVIq8AwTlnZ5MN8d&q-sign-time=1758695170%3B1758781570&q-key-time=1758695170%3B1758781570&q-header-list=host&q-url-param-list=&q-signature=c47edccc3cbb601245ddf2de8a39c618f1305fbd","PreviewImageUrl":"https://hunyuan-prod-1258344699.cos.ap-guangzhou.tencentcos.cn/%2F3d/output/1257289198/preview_6b726e7e-4ad9-4484-8539-85455a801f13_0.png?q-sign-algorithm=sha1&q-ak=AKIDpRovliU1IJ5ctufBSVIq8AwTlnZ5MN8d&q-sign-time=1758695170%3B1758781570&q-key-time=1758695170%3B1758781570&q-header-list=host&q-url-param-list=&q-signature=90f6e17da43901ffc3d77468ae59dbdd3829d7f3"}],"RequestId":"7fd99736-6a2c-476a-bb51-8f6786443fc4"}
     * @throws TencentCloudSDKException 腾讯云异常
     */
    public static QueryHunyuanTo3DRapidJobResponse queryHunyuanTo3DJobForRapid(String secretId,String secretKey, String region, String jobId) throws TencentCloudSDKException {
        Ai3dClient client = getAi3dClient(secretId, secretKey, region);
        // 实例化一个请求对象,每个接口都会对应一个request对象
        QueryHunyuanTo3DRapidJobRequest req = new QueryHunyuanTo3DRapidJobRequest();
        // 设置请求参数 - 任务ID
        req.setJobId(jobId);
        // 返回的resp是一个QueryHunyuanTo3DProJobResponse的实例，与请求对象对应
        QueryHunyuanTo3DRapidJobResponse resp = client.QueryHunyuanTo3DRapidJob(req);
        // 输出json格式的字符串回包
        System.out.println(AbstractModel.toJsonString(resp));
        return resp;
    }

    /**
     * 获取Ai3dClient示例对象
     * @param secretId
     * @param secretKey
     * @param region
     * @return
     */
    private static Ai3dClient getAi3dClient(String secretId, String secretKey, String region){
        // 构造凭证
        Credential cred = new Credential(secretId, secretKey);
        // 实例化一个http选项，可选的，没有特殊需求可以跳过
        HttpProfile httpProfile = new HttpProfile();
        httpProfile.setEndpoint("ai3d.tencentcloudapi.com");
        // 实例化一个client选项，可选的，没有特殊需求可以跳过
        ClientProfile clientProfile = new ClientProfile();
        clientProfile.setHttpProfile(httpProfile);
        // 实例化要请求产品的client对象,clientProfile是可选的
        return new Ai3dClient(cred, region, clientProfile);
    }

    /**
     * 0-WAIT：等待中，1-RUN：执行中，2-FAIL：任务失败，3-DONE：任务成功
     * @param status string状态
     * @return int状态码
     */
    public static int getJobStatus(String status){
        return switch (status) {
            case "WAIT" -> 0;
            case "RUN" -> 1;
            case "FAIL" -> 2;
            case "DONE" -> 3;
            default -> -1;
        };
    }
}
